package com.shasselclub.api.weixin.common;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.json.JSONException;
import org.json.JSONObject;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.net.URI;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@Slf4j
public class JsApiTicketUtil {
    /**
     * 官方文档：https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
     *
     * 获取jsapi_ticket
     *
     *
     *  生成签名之前必须先了解一下jsapi_ticket，jsapi_ticket是公众号用于调用微信JS接口的临时票据。
     *  正常情况下，jsapi_ticket的有效期为7200秒，通过access_token来获取。
     *  由于获取jsapi_ticket的api调用次数非常有限，频繁刷新jsapi_ticket会导致api调用受限，影响自身业务，开发者必须在自己的服务全局缓存jsapi_ticket 。
     *
     * 参考以下文档获取access_token（有效期7200秒，开发者必须在自己的服务全局缓存access_token）：
     * https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
     *
     * 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket（有效期7200秒，开发者必须在自己的服务全局缓存jsapi_ticket）：
     * https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
     *
     * @return
     */
    public String getJsapiTicket(String appid,String secret) {
        String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
        tokenUrl = tokenUrl + "&appid=" + appid + "&secret=" + secret;
        JSONObject tokenJson=new JSONObject();
        tokenJson=getUrlResponse(tokenUrl);
        log.info("===============tokenJson：{}============" , tokenJson.toString());
        String token="";
        try {
            token=tokenJson.getString("access_token");
        } catch (JSONException e) {
            e.printStackTrace();
            log.info("===============报错了{}============" , e);
            System.out.println("报错了");
            return null;
        }
        String jsapiTicketUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
        JSONObject jsapiTickeJson=new JSONObject();
        System.out.println("getJsapiTicket：获取token："+token);
        if(StringUtils.isNotBlank(token)){
            jsapiTicketUrl = jsapiTicketUrl.replace("ACCESS_TOKEN",token);
            jsapiTickeJson=getUrlResponse(jsapiTicketUrl);
            // System.out.println("tokenJson:"+jsapiTickeJson.toString());
            log.info("===============tokenJson：{}============" ,jsapiTickeJson.toString());
            try {
                return (String) jsapiTickeJson.get("ticket");
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }
        }else{
            return null;
        }
    }

    private  JSONObject getUrlResponse(String url){
        CharsetHandler handler = new CharsetHandler("UTF-8");
        try {
            HttpGet httpget = new HttpGet(new URI(url));
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            //HttpClient
            CloseableHttpClient client = httpClientBuilder.build();
            client = (CloseableHttpClient) wrapClient(client);
            return new JSONObject(client.execute(httpget, handler));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    private static HttpClient wrapClient(HttpClient base) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLSv1");
            X509TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] xcs,
                                               String string) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] xcs,
                                               String string) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            return httpclient;

        } catch (Exception ex) {
            return null;
        }
    }
}
